﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Simple.Common.Configuration;
using Simple.Common.Middlewares;
using Simple.Repository.Models;
using Simple.Repository.Models.DeviceManagement;
using Simple.Repository.Models.Market;
using Simple.Repository.Models.MorningCheck;
using Simple.Services.System.FileInfo;
using Simple.Services.System.Market.Models;
using Simple.Services.System.MorningCheck.Models;

namespace Simple.Services.System.MorningCheck
{
    /// <summary>
    /// 晨检管理
    /// </summary>
    public class MorningCheckService : BusinessBaseService
    {
        private readonly SimpleDbContext _context;
        private readonly ILogger _logger;


        public MorningCheckService(SimpleDbContext context,
            ISimpleService services,
            ILogger<ApiExceptionMiddleware> logger) : base(services)
        {
            _context = context;
            _logger = logger;

        }

        /// <summary>
        /// 添加晨检记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> AddAsync(MCheckRecordCreateOrUpdateModel model)
        {
            var cInfo = await _context.Set<Childrens>().FirstOrDefaultAsync(m => m.Id == model.ChildrenId);
            if (cInfo == null)
            {
                throw AppResultException.Status409Conflict("学生信息不存在！");
            }
            if (model.BodyTemperature <= 0)
            {
                throw AppResultException.Status409Conflict("体温无效！");
            }
            DateTime sTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
            DateTime eTime = sTime.AddDays(1);
            if (await _context.Set<MCheckRecord>().FirstOrDefaultAsync(m => m.ChildrenId == model.ChildrenId && m.CreatedTime >= sTime && m.CreatedTime < eTime) != null)
            {
                throw AppResultException.Status409Conflict($"今日[{cInfo.Name}]已添加晨检记录啦！");
            }

            var record = MapperHelper.Map<MCheckRecord>(model);
            if (!string.IsNullOrEmpty(cInfo.ClassesId))
                record.ClassesId = Guid.Parse(cInfo.ClassesId);
            record.ChildrenName = cInfo.Name;
            record.IsSuccess = true;
            await _context.AddAsync(record);
            return await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 修改晨检记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> UpdateAsync(MCheckRecordCreateOrUpdateModel model)
        {
            if (!model.Id.HasValue)
            {
                throw AppResultException.Status409Conflict("参数错误,晨检记录Id参数不能为Null!");
            }
            if (model.BodyTemperature <= 0)
            {
                throw AppResultException.Status409Conflict("体温无效！");
            }
            var info = await _context.Set<MCheckRecord>()
                .FirstOrDefaultAsync(m => model.Id == m.Id);

            if (info == null)
            {
                throw AppResultException.Status409Conflict("晨检记录不存在！");
            }

            info.ThroatType = model.ThroatType;
            info.BodyTemperature = model.BodyTemperature;

            _context.Update(info);
            int ret = await _context.SaveChangesAsync();

            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;
        }

        /// <summary>
        /// 晨检详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<MCheckRecordModel> GetAsync(Guid? id)
        {
            if (!id.HasValue)
            {
                throw AppResultException.Status409Conflict("参数错误,晨检记录Id参数不能为Null!");
            }

            var info = await _context.Set<MCheckRecord>()
               .FirstOrDefaultAsync(m => id == m.Id);

            if (info == null)
            {
                throw AppResultException.Status409Conflict("未找到相关晨检记录数据!");
            }

            var outResult = MapperHelper.Map<MCheckRecordModel>(info);

            var childrenInfo = await _context.Set<Childrens>()
               .FirstOrDefaultAsync(m => info.ChildrenId == m.Id);
            if (childrenInfo != null && childrenInfo.ClassesId != null)
            {
                if (childrenInfo.Birthday.HasValue)
                {
                    outResult.Age = AgeHelper.ToAgeStr(childrenInfo.Birthday.Value);
                }
                outResult.Gender = childrenInfo.Gender;
                if (!string.IsNullOrEmpty(childrenInfo.ClassesId))
                {
                    Guid _classId = Guid.Parse(childrenInfo.ClassesId);
                    var calssInfo = await _context.Set<SysClasses>().FirstOrDefaultAsync(m => _classId == m.Id);
                    if (calssInfo != null)
                    {
                        outResult.ClassName = calssInfo.Name;
                    }
                }
            }

            outResult.RecordTime = info.CreatedTime.Value.ToString("yyyy-MM-dd");

            return outResult;
        }

        /// <summary>
        /// 晨检记录分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResultModel<MCheckRecordViewModel>> GetPageAsync(MCheckRecordPageQueryModel input)
        {
            var result = new PageResultModel<MCheckRecordViewModel>();
            DateTime sTime = DateTime.Parse(input.QueryTime.ToString("yyyy-MM-dd"));
            DateTime nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
            if (sTime > nowTime)
            {
                return result;
            }

            var returnLists = new List<MCheckRecordModel>();
            //全园所有学生
            var childrens = await OrganizationFilter(_context.Set<Childrens>());
            childrens = childrens.Where(x => x.ChildState == EnumChildState.Reading);

            //所有班级信息
            var classInfos = await OrganizationFilter(_context.Set<SysClasses>().AsQueryable());
            var classLists = await classInfos.ToListAsync();
            DateTime eTime = sTime.AddDays(1);
            var records = await _context.Set<MCheckRecord>().Where(m => m.CreatedTime >= sTime && m.CreatedTime < eTime).ToListAsync();

            if (input.ClassId.HasValue && records != null && records.Count > 0)
            {
                records = records.Where(m => m.ClassesId == input.ClassId).ToList();
                string _classId = input.ClassId.ToString();
                childrens = childrens.Where(x => x.ClassesId == _classId);
            }
            if (!string.IsNullOrEmpty(input.ChildrenName) && records != null && records.Count > 0)
            {
                records = records.Where(m => m.ChildrenName.Contains(input.ChildrenName)).ToList();
                childrens = childrens.Where(x => x.Name.Contains(input.ChildrenName));
            }

            //组装数据
            bool isRecords = false;
            if (records != null && records.Count > 0)
                isRecords = true;
            var childrenLists = await childrens.ToListAsync();
            if (childrenLists != null && childrenLists.Count > 0)
            {
                foreach (var c in childrenLists)
                {
                    string className = "";
                    if (!string.IsNullOrEmpty(c.ClassesId))
                    {
                        Guid _classId = Guid.Parse(c.ClassesId);
                        className = classLists.FirstOrDefault(x => x.Id == _classId).Name;
                    }
                    MCheckRecordModel mCheckRecordModel = new MCheckRecordModel
                    {
                        Age = c.Birthday.HasValue ? AgeHelper.ToAgeStr(c.Birthday.Value) : null,
                        BodyTemperature = null,
                        ChildrenId = c.Id,
                        ChildrenName = c.Name,
                        ClassesId = !string.IsNullOrEmpty(c.ClassesId) ? Guid.Parse(c.ClassesId) : null,
                        ClassName = className,
                        Gender = c.Gender,
                        Id = null,
                        RecordTime = input.QueryTime.ToString("yyyy-MM-dd"),
                        //ThroatType = null
                    };

                    if (isRecords && records.Any(x => x.ChildrenId == c.Id))
                    {
                        var current_Recoed = records.FirstOrDefault(x => x.ChildrenId == c.Id);
                        mCheckRecordModel.BodyTemperature = current_Recoed.BodyTemperature;
                        mCheckRecordModel.Id = current_Recoed.Id;
                        mCheckRecordModel.ThroatType = current_Recoed.ThroatType.Value;
                        mCheckRecordModel.IsSuccess = current_Recoed.IsSuccess;
                    }

                    returnLists.Add(mCheckRecordModel);
                }

                if (returnLists != null && returnLists.Count > 0)
                {
                    var noCheckList = returnLists.Where(x => !x.BodyTemperature.HasValue).ToList();
                    // 排序
                    var checkList = returnLists.Where(x => x.BodyTemperature.HasValue).OrderByDescending(m => m.BodyTemperature).ThenByDescending(m => m.ThroatType).ToList();

                    var resultList = new List<MCheckRecordModel>();
                    resultList.AddRange(noCheckList);
                    resultList.AddRange(checkList);

                    var noCheckCount = noCheckList.Count;
                    var abnormalCount = resultList.Where(x => x.ThroatType != ThroatTypeEnum.Normal).Count();

                    var dataList = new List<MCheckRecordViewModel>();
                    var view = new MCheckRecordViewModel();
                    view.NoCheckCount = noCheckCount;
                    view.AbnormalCount = abnormalCount;
                    view.CheckList = resultList.Skip((input.PageNo - 1) * input.PageSize).Take(input.PageSize).ToList();
                    dataList.Add(view);

                    // 获取总数量
                    result.TotalRows = resultList.Count;
                    // 分页查询
                    result.Rows = dataList;
                    result.SetPage(input);
                    result.CountTotalPage();
                }
            }
            return result;
        }

        /// <summary>
        /// 晨检记录分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResultModel<MCheckRecordMobileModel>> GetMobilePageAsync(MCheckRecordMobilePageQueryModel input)
        {
            var result = new PageResultModel<MCheckRecordMobileModel>();
            DateTime sTime = DateTime.Parse(input.QueryTime.ToString("yyyy-MM-01"));
            DateTime nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-01"));
            if (sTime > nowTime)
            {
                return result;
            }

            var returnLists = new List<MCheckRecordMobileModel>();

            DateTime eTime = sTime.AddMonths(1);
            var records = await _context.Set<MCheckRecord>().Where(m => m.CreatedTime >= sTime && m.CreatedTime < eTime && m.ChildrenId == input.ChildrenId).ToListAsync();

            //组装数据
            if (records != null && records.Count > 0)
            {
                records = records.OrderByDescending(m => m.CreatedTime).ToList();

                foreach (var r in records)
                {
                    MCheckRecordMobileModel mCheckRecordMobileModel = new MCheckRecordMobileModel
                    {
                        BodyTemperature = r.BodyTemperature,
                        Id = r.Id,
                        RecordTime = r.CreatedTime.Value.Day.ToString() + "号",
                        ThroatType = r.ThroatType.Value,
                        IsSuccess = r.IsSuccess
                    };
                    returnLists.Add(mCheckRecordMobileModel);
                }

                if (returnLists != null && returnLists.Count > 0)
                {
                    // 获取总数量
                    result.TotalRows = returnLists.Count;
                    // 分页查询
                    result.Rows = returnLists.Skip((input.PageNo - 1) * input.PageSize).Take(input.PageSize).ToList();
                    result.SetPage(input);
                    result.CountTotalPage();
                }
            }
            return result;
        }

        /// <summary>
        /// 数据同步(陌生人模式)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> DataSynchronismAsync(DataSynchronismModel model)
        { 
            //第三方数据交互
            var mCheckRecords = new List<MCheckRecord>();

            //数据处理
            if (model != null && model.count > 0)
            {
                DateTime sTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
                DateTime eTime = sTime.AddDays(1);
                var records_Today = await _context.Set<MCheckRecord>()
                    .Where(m => m.CreatedTime >= sTime && m.CreatedTime < eTime).ToListAsync();
                //全园所有学生
                var childrens = await _context.Set<Childrens>()
                    .Where(x => x.ChildState == EnumChildState.Reading).ToListAsync();
                //所有音响设备
                //var devices = await _context.Set<Device>().ToListAsync();

                var adminInfo = await _context.Set<SysUser>().FirstAsync(x => x.UserName == "superAdmin");

                foreach (var l in model.logs)
                {
                    var cu = childrens.FirstOrDefault(x => x.Name == l.user_name);
                    DateTime logTime = DateTime.Parse(l.recog_time);
                    if (cu != null && logTime > sTime && (records_Today == null || records_Today.Count == 0 ||
                        records_Today.FirstOrDefault(x => x.ChildrenId == cu.Id) == null))
                    {
                        mCheckRecords.Add(
                            new MCheckRecord
                            {
                                ChildrenId = cu.Id,
                                BodyTemperature = l.body_temperature,
                                ChildrenName = cu.Name,
                                CreatedTime = logTime,
                                ThroatType = ThroatTypeEnum.Normal,
                                ClassesId = string.IsNullOrEmpty(cu.ClassesId) ? null : Guid.Parse(cu.ClassesId),
                                OrganizationId = adminInfo?.OrganizationId,
                                IsSuccess = true
                            }
                            );
                        //string voicetemp = AppSettings.DeviceConfig.VoiceTemp;
                        //string posturl = AppSettings.DeviceConfig.PostUrl;
                        ////推送到音响
                        //if (!string.IsNullOrEmpty(cu.ClassesId) && devices != null && devices.Count > 0 && !string.IsNullOrEmpty(voicetemp) && !string.IsNullOrEmpty(posturl))
                        //{
                        //    var classesId = Guid.Parse(cu.ClassesId);
                        //    var c_device = devices.FirstOrDefault(x => x.ClassesId == classesId);
                        //    if (c_device != null)
                        //    {
                        //        posturl = string.Format(posturl, c_device.IpAddress);
                        //        voicetemp = string.Format(voicetemp, cu.Name);
                        //        DevicePlayModelcs devicePlayModelcs = new DevicePlayModelcs { text = voicetemp };
                        //        var ps = JsonConvert.SerializeObject(devicePlayModelcs);
                        //        RequestHelper.DevicePost(posturl, ps);
                        //    }
                        //}
                    }
                }
                if (mCheckRecords != null && mCheckRecords.Count > 0)
                {
                    await _context.AddRangeAsync(mCheckRecords);
                    await _context.SaveChangesAsync();

                    return 1;
                }
            }
            return 0;
        }

        /// <summary>
        /// 数据同步（员工模式）
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> DataSynchronismFaceAsync(DataSynchronismFaceModel model)
        {
          
            //第三方数据交互
            var mCheckRecords = new List<MCheckRecord>();

            //数据处理
            if (model != null && model.count > 0)
            {
                DateTime sTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
                DateTime eTime = sTime.AddDays(1);
                var records_Today = await _context.Set<MCheckRecord>()
                    .Where(m => m.CreatedTime >= sTime && m.CreatedTime < eTime).ToListAsync();
                //全园所有学生
                var childrens = await _context.Set<Childrens>()
                    .Where(x => x.ChildState == EnumChildState.Reading).ToListAsync();

                var sysClassesInfos = await _context.Set<SysClasses>().Where(x => x.OrganizationId != null).ToListAsync();

                foreach (var l in model.logs)
                {
                    var cu = childrens.FirstOrDefault(x => x.StudentNumber == l.user_id);
                    DateTime logTime = DateTime.Parse(l.recog_time);
                    if (cu != null && logTime > sTime && (records_Today == null || records_Today.Count == 0 ||
                        records_Today.FirstOrDefault(x => x.ChildrenId == cu.Id) == null))
                    {
                        ThroatTypeEnum _ThroatType = ThroatTypeEnum.Normal;
                        bool _IsSuccess = true;
                        if (l.user_action == "1")
                        {
                            //晨检不通过
                            _IsSuccess = false;
                        }

                        try
                        {
                            _ThroatType = (ThroatTypeEnum)int.Parse(l.user_throat_action);
                        }
                        catch { }


                        mCheckRecords.Add(
                            new MCheckRecord
                            {
                                ChildrenId = cu.Id,
                                BodyTemperature = decimal.Parse(l.body_temperature),
                                ChildrenName = cu.Name,
                                CreatedTime = logTime,
                                ThroatType = _ThroatType,
                                ClassesId = string.IsNullOrEmpty(cu.ClassesId) ? null : Guid.Parse(cu.ClassesId),
                                OrganizationId = sysClassesInfos.First()?.OrganizationId,
                                IsSuccess = _IsSuccess
                            }
                            );
                    }
                }
                if (mCheckRecords != null && mCheckRecords.Count > 0)
                {
                    await _context.AddRangeAsync(mCheckRecords);
                    await _context.SaveChangesAsync();

                    return 1;
                }
            }
            return 0;
        }

        /// <summary>
        /// 今日设备数据同步后的最新数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<MCheckRecordModel> GetLastAsync()
        {
            DateTime sTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
            DateTime eTime = sTime.AddDays(1);
            var records_Today = await _context.Set<MCheckRecord>()
                .Where(m => m.CreatedTime >= sTime && m.CreatedTime < eTime && m.CreatedUserId == null).ToListAsync();

            if (records_Today == null || records_Today.Count == 0)
            {
                throw AppResultException.Status409Conflict("今日未产生晨检记录!");
            }

            var info = records_Today.OrderByDescending(x => x.CreatedTime).First();

            var outResult = MapperHelper.Map<MCheckRecordModel>(info);

            var childrenInfo = await _context.Set<Childrens>()
               .FirstOrDefaultAsync(m => info.ChildrenId == m.Id);
            if (childrenInfo != null && childrenInfo.ClassesId != null)
            {
                if (childrenInfo.Birthday.HasValue)
                {
                    outResult.Age = AgeHelper.ToAgeStr(childrenInfo.Birthday.Value);
                }
                outResult.Gender = childrenInfo.Gender;
                if (!string.IsNullOrEmpty(childrenInfo.ClassesId))
                {
                    Guid _classId = Guid.Parse(childrenInfo.ClassesId);
                    var calssInfo = await _context.Set<SysClasses>().FirstOrDefaultAsync(m => _classId == m.Id);
                    if (calssInfo != null)
                    {
                        outResult.ClassName = calssInfo.Name;
                    }
                }
            }

            outResult.RecordTime = info.CreatedTime.Value.ToString("yyyy-MM-dd");

            return outResult;
        }


    }
}
